﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.BizTalk.ExplorerOM;
using System.Diagnostics;
using Microsoft.BizTalk.Operations;
using System.Management;
using Microsoft.Win32;

namespace BizMock
{
    public sealed class BizTalkExplorerHelper
    {


        //private const string btsDbName = ;
        //private const string DbServer = "localhost";
        private const string BizMockEventSource = "BizMock";

        private static string BizTalkConnectionString = "server=.;database=BizTalkMgmtDb;Integrated Security=SSPI";
        //private static string BizTalkInstallPath = string.Empty;
        //private static string BizTalkPathTracking = string.Empty;
        //private static string BizTalkPathPipelineComponent = string.Empty;
        private static string BizTalkDbServer = "BizTalkMgmtDb";
        private static string BizTalkDbTable = "localhost";
        //private static string BizTalkGroupName = string.Empty;
        private static readonly bool OS64Bit;
        //private static bool MachineHasBizTalk;
        //private static bool MachineHasBizTalkAdministration;
        private const string ConnectionStringTemplate = "server={0};database={1};Integrated Security=SSPI";

        /*
         * Cláudio Silva - dynamic biztalk settings
         */

        static BizTalkExplorerHelper()
        {
            RegistryKey regKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Wow6432Node\\Microsoft\\MSBuild");
            OS64Bit = null != regKey;
            SetVariables();
        }

        private static void SetVariables()
        {
            string key = "SOFTWARE\\" + (OS64Bit ? "Wow6432Node\\" : "") + "Microsoft\\Biztalk Server\\3.0";
            var regKey = Registry.LocalMachine.OpenSubKey(key);
            if (null == regKey)
            {
                throw new Exception("No BizTalk installed!");
            }
            //MachineHasBizTalk = true;
            //BizTalkInstallPath = (string) regKey.GetValue("InstallPath");
            //BizTalkPathTracking = BizTalkInstallPath + "\\Tracking";
            //BizTalkPathPipelineComponent = BizTalkInstallPath + "\\Pipeline Components";

            key += "\\Administration";
            regKey = Registry.LocalMachine.OpenSubKey(key);
            if (null == regKey)
            {
                throw new Exception("No BizTalk Administration installed!");
            }
            //MachineHasBizTalkAdministration = true;
            BizTalkDbServer = (string)regKey.GetValue("MgmtDBServer");
            BizTalkDbTable = (string)regKey.GetValue("MgmtDBName");
            //BizTalkGroupName = (string)regKey.GetValue("BizTalkGroupName");
            BizTalkConnectionString = string.Format(ConnectionStringTemplate, BizTalkDbServer, BizTalkDbTable);
            //else
            //{
            //    MachineHasBizTalkAdministration = false;
            //}
        }

        public static Application GetApplication(string appName)
        {

            var myGroup = new Microsoft.BizTalk.ApplicationDeployment.Group { DBName = BizTalkDbTable, DBServer = BizTalkDbServer };

            var explorer = (BtsCatalogExplorer)myGroup.CreateInstance(typeof(BtsCatalogExplorer));
            explorer.Refresh();
            try
            {
                var applications = explorer.Applications;
                var application = applications[appName];
                if (application != null)
                {
                    return application;
                }
                else
                {
                    throw new BizMockException(String.Format("{0} does not exist in database [{1}] on server [{2}]", appName, myGroup.DBName, myGroup.DBServer));
                }
            }
            catch (Exception ex)
            {
                explorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static void ApplyChanges(Application application)
        {
            application.BtsCatalogExplorer.SaveChanges();
        }

        public static void EnableReceiveLocation(Application application, string receiveLocationName, bool enable)
        {
            try
            {
                foreach (ReceivePort rp in application.ReceivePorts)
                {
                    foreach (ReceiveLocation rcl in rp.ReceiveLocations)
                    {
                        if (rcl.Name == receiveLocationName)
                        {
                            rcl.Enable = enable;
                            return;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static ReceiveLocationInfo GetDeployedReceiveLocationInfo(Application application, string receivePortName, string receiveLocationName)
        {
            ReceiveLocationInfo rclInfo = new ReceiveLocationInfo();
            try
            {
                foreach (ReceivePort rp in application.ReceivePorts)
                {
                    foreach (ReceiveLocation rcl in rp.ReceiveLocations)
                    {
                        if (rcl.Name == receiveLocationName)
                        {
                            rclInfo.Name = rcl.Name;
                            rclInfo.TransportTypeData = rcl.TransportTypeData;
                            return rclInfo;
                        }
                    }
                }
                return null;
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static SendPortInfo GetDeployedSendPortInfo(Application application, string sendPortName)
        {
            SendPortInfo spInfo = new SendPortInfo();
            try
            {
                foreach (SendPort sp in application.SendPorts)
                {
                    if (sp.Name == sendPortName)
                    {
                        spInfo.Name = sp.Name;
                        spInfo.TransportTypeData = sp.PrimaryTransport.TransportTypeData;
                        return spInfo;
                    }
                }
                return null;
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static void RemoveReceiveLocation(Application application, string receiveLocationName)
        {

            try
            {
                foreach (ReceivePort rp in application.ReceivePorts)
                {
                    foreach (ReceiveLocation rcl in rp.ReceiveLocations)
                    {
                        if (rcl.Name == receiveLocationName && rp.ReceiveLocations.Count == 1)
                        {
                            application.BtsCatalogExplorer.RemoveReceivePort(rp);
                            return;
                        }
                        else if (rcl.Name == receiveLocationName && !rcl.IsPrimary)
                        {
                            rp.RemoveReceiveLocation(rcl);
                            return;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                application.BtsCatalogExplorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static void RemoveReceivePort(Application application, string receivePortName)
        {
            try
            {
                foreach (ReceivePort rp in application.ReceivePorts)
                {
                    if (rp.Name == receivePortName)
                    {
                        application.BtsCatalogExplorer.RemoveReceivePort(rp);
                        return;
                    }
                }
            }
            catch (Exception ex)
            {
                application.BtsCatalogExplorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static void RemoveSendPort(Application application, string sendPortName)
        {

            try
            {
                foreach (SendPort sp in application.SendPorts)
                {
                    if (sp.Name == sendPortName)
                    {
                        sp.Status = PortStatus.Bound;
                        application.BtsCatalogExplorer.RemoveSendPort(sp);

                        return;
                    }
                }
            }
            catch (Exception ex)
            {
                application.BtsCatalogExplorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static void CreateNewReceiveLocation(Application application, string receivePortName, string receiveLocationName, string receivePipelineFullName, string receivePipelineData, string sendPipelineFullName, string sendPipelineData, int timeout, bool twoWay)
        {
            if (string.IsNullOrEmpty(receivePipelineFullName))
                receivePipelineFullName = "Microsoft.BizTalk.DefaultPipelines.XMLReceive";

            if (string.IsNullOrEmpty(sendPipelineFullName))
                sendPipelineFullName = "Microsoft.BizTalk.DefaultPipelines.XMLTransmit";

            try
            {
                ReceivePort myreceivePort = null;
                ReceiveLocation myreceiveLocation = null;
                foreach (ReceivePort rp in application.ReceivePorts)
                {
                    if (rp.Name == receivePortName)
                        myreceivePort = rp;
                    foreach (ReceiveLocation rcl in rp.ReceiveLocations)
                    {
                        if (rp.Name != receivePortName || rcl.Name != receiveLocationName) continue;
                        if (rcl.Enable != true)
                        {
                            rcl.Enable = true;
                        }
                        myreceiveLocation = rcl;
                        break;
                    }
                }

                if (myreceivePort == null)
                {
                    myreceivePort = application.AddNewReceivePort(twoWay);
                    myreceivePort.Name = receivePortName;
                }

                if (myreceiveLocation == null)
                {
                    myreceiveLocation = myreceivePort.AddNewReceiveLocation();
                    myreceiveLocation.Name = receiveLocationName;
                }

                foreach (ReceiveHandler handler in application.BtsCatalogExplorer.ReceiveHandlers)
                {
                    if (handler.TransportType.Name != "BizMock") continue;
                    myreceiveLocation.ReceiveHandler = handler;
                    break;
                }

                foreach (ProtocolType protocol in application.BtsCatalogExplorer.ProtocolTypes)
                {
                    if (protocol.Name != "BizMock") continue;
                    myreceiveLocation.TransportType = protocol;
                    break;
                }

                myreceiveLocation.Address = "BizMock://" + receiveLocationName;

                foreach (Pipeline pipeline in application.BtsCatalogExplorer.Pipelines)
                {
                    if (pipeline.FullName == receivePipelineFullName)
                    {
                        myreceiveLocation.ReceivePipeline = pipeline;
                    }
                    else if (twoWay && pipeline.FullName == sendPipelineFullName)
                    {
                        myreceiveLocation.SendPipeline = pipeline;
                    }
                }

                if (receivePipelineData != null)
                    myreceiveLocation.ReceivePipelineData = receivePipelineData;
                if (sendPipelineData != null)
                    myreceiveLocation.SendPipelineData = sendPipelineData;

                myreceiveLocation.Enable = true;
                myreceiveLocation.TransportTypeData = string.Format("<CustomProps><AdapterConfig vt=\"8\">&lt;Config xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"&gt;&lt;name&gt;{0}&lt;/name&gt;&lt;timeout&gt;{1}&lt;/timeout&gt;&lt;uri&gt;BizMock://{0}&lt;/uri&gt;&lt;/Config&gt;</AdapterConfig></CustomProps>", receiveLocationName, timeout);


            }
            catch (Exception ex)
            {
                application.BtsCatalogExplorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static void CreateNewSendPort(Application application, string sendPortName, string sendPipelineFullName, string sendPipelineData, string receivePipelineFullName, string receivePipelineData, int timeout, bool twoWay, bool dynamicPort)
        {
            if (string.IsNullOrEmpty(receivePipelineFullName))
                receivePipelineFullName = "Microsoft.BizTalk.DefaultPipelines.XMLReceive";

            if (string.IsNullOrEmpty(sendPipelineFullName))
                sendPipelineFullName = "Microsoft.BizTalk.DefaultPipelines.XMLTransmit";

            try
            {
                SendPort mysendPort = null;
                foreach (SendPort sp in application.SendPorts)
                {
                    if (sp.Name != sendPortName) continue;
                    if (sp.Status != PortStatus.Started)
                    {
                        sp.Status = PortStatus.Started;
                    }
                    mysendPort = sp;
                    break;
                }

                if (mysendPort == null)
                {
                    mysendPort = application.AddNewSendPort(dynamicPort, twoWay);
                    mysendPort.Name = sendPortName;
                }

                if (mysendPort.PrimaryTransport != null)
                {
                    foreach (ProtocolType protocol in application.BtsCatalogExplorer.ProtocolTypes)
                    {
                        if (protocol.Name != "BizMock") continue;
                        mysendPort.PrimaryTransport.TransportType = protocol;
                        break;
                    }

                    mysendPort.PrimaryTransport.Address = "BizMock://" + sendPortName;

                    mysendPort.PrimaryTransport.TransportTypeData = string.Format("<CustomProps><AdapterConfig vt=\"8\">&lt;Config xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"&gt;&lt;name&gt;{0}&lt;/name&gt;&lt;timeout&gt;{1}&lt;/timeout&gt;&lt;uri&gt;BizMock://{0}&lt;/uri&gt;&lt;/Config&gt;</AdapterConfig></CustomProps>", sendPortName, timeout);
                }

                foreach (Pipeline pipeline in application.BtsCatalogExplorer.Pipelines)
                {
                    if (pipeline.FullName == sendPipelineFullName)
                    {
                        mysendPort.SendPipeline = pipeline;
                    }
                    else if (twoWay && pipeline.FullName == receivePipelineFullName)
                    {
                        mysendPort.ReceivePipeline = pipeline;
                    }
                }

                mysendPort.Status = PortStatus.Started;

            }
            catch (Exception ex)
            {
                application.BtsCatalogExplorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static void BindOrchestration(Application application, string orchestrationFullName, Dictionary<string, string> bindingMap)
        {
            try
            {
                foreach (BtsOrchestration orch in application.Orchestrations)
                {
                    if (orch.FullName != orchestrationFullName) continue;
                    orch.Status = OrchestrationStatus.Unenlisted;
                    foreach (OrchestrationPort orchPort in orch.Ports)
                    {

                        bool found = false;

                        foreach (ReceivePort rp in application.ReceivePorts)
                        {
                            if (!bindingMap.ContainsKey(rp.Name) || bindingMap[rp.Name] != orchPort.Name) continue;
                            orchPort.ReceivePort = rp;
                            found = true;
                            break;
                        }
                        if (!found)
                        {
                            foreach (SendPort sp in application.SendPorts)
                            {
                                if (!bindingMap.ContainsKey(sp.Name) || bindingMap[sp.Name] != orchPort.Name) continue;
                                orchPort.SendPort = sp;
                                break;
                            }
                        }
                    }
                    foreach (Host host in application.BtsCatalogExplorer.Hosts)
                    {
                        orch.Host = host;
                        break;
                    }
                    orch.Status = OrchestrationStatus.Enlisted;

                    break;
                }


            }
            catch (Exception ex)
            {
                application.BtsCatalogExplorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }

        }

        public static void UnBindOrchestration(Application application, string orchestrationFullName)
        {
            try
            {
                foreach (BtsOrchestration orch in application.Orchestrations)
                {
                    if (orch.FullName != orchestrationFullName) continue;
                    orch.Status = OrchestrationStatus.Unenlisted;
                    foreach (OrchestrationPort orchPort in orch.Ports)
                    {

                        orchPort.ReceivePort = null;
                        orchPort.SendPort = null;
                    }

                    break;
                }

            }
            catch (Exception ex)
            {
                application.BtsCatalogExplorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }

        }

        public static string GetOrchestrationStatus(Application application, string orchestrationFullName)
        {
            try
            {
                foreach (BtsOrchestration orch in application.Orchestrations)
                {
                    if (orch.FullName == orchestrationFullName)
                    {
                        return orch.Status.ToString();
                    }
                }
                return null;
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }

        }

        public static void StopOrchestration(Application application, string orchestrationFullName)
        {
            try
            {
                foreach (BtsOrchestration orch in application.Orchestrations)
                {
                    if (orch.FullName != orchestrationFullName) continue;
                    orch.Status = OrchestrationStatus.Unenlisted;
                    break;
                }

            }
            catch (Exception ex)
            {
                application.BtsCatalogExplorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static void StopOrchestrations(Application application, List<string> orchestrations)
        {
            try
            {
                foreach (BtsOrchestration orch in application.Orchestrations)
                {
                    if (orchestrations.Contains(orch.FullName))
                    {
                        orch.Status = OrchestrationStatus.Unenlisted;
                    }
                }

            }
            catch (Exception ex)
            {
                application.BtsCatalogExplorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static void StopAllOrchestrations(Application application)
        {
            try
            {
                foreach (BtsOrchestration orch in application.Orchestrations)
                {
                    orch.Status = OrchestrationStatus.Unenlisted;
                }

            }
            catch (Exception ex)
            {
                application.BtsCatalogExplorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static void StartOrchestration(Application application, string orchestrationFullName)
        {
            try
            {
                foreach (BtsOrchestration orch in application.Orchestrations)
                {
                    if (orch.FullName != orchestrationFullName) continue;
                    orch.Status = OrchestrationStatus.Started;
                    break;
                }

            }
            catch (Exception ex)
            {
                application.BtsCatalogExplorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static void StartOrchestrations(Application application, List<string> orchestrations)
        {
            try
            {
                foreach (BtsOrchestration orch in application.Orchestrations)
                {
                    if (orchestrations.Contains(orch.FullName))
                    {
                        orch.Status = OrchestrationStatus.Started;
                    }
                }

            }
            catch (Exception ex)
            {
                application.BtsCatalogExplorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static void StartAllOrchestrations(Application application)
        {
            try
            {
                foreach (BtsOrchestration orch in application.Orchestrations)
                {
                    orch.Status = OrchestrationStatus.Started;
                }

            }
            catch (Exception ex)
            {
                application.BtsCatalogExplorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static void DeleteAllInstances()
        {
            try
            {
                var ops = new BizTalkOperations(BizTalkDbServer, BizTalkDbTable);

                var enumerable = ops.GetServiceInstances();

                foreach (Instance msg in enumerable)
                {
                    ops.TerminateInstance(msg.ID);
                }
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw new BizMockException("DeleteAllInstances", ex);
            }
        }

        public static void DisableReceiveLocations(Application application)
        {
            try
            {
                foreach (ReceivePort rp in application.ReceivePorts)
                {
                    foreach (ReceiveLocation rcl in rp.ReceiveLocations)
                    {
                        if (rcl.Enable)
                        {
                            rcl.Enable = false;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                application.BtsCatalogExplorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static void EnableReceiveLocations(Application application)
        {
            try
            {
                foreach (ReceivePort rp in application.ReceivePorts)
                {
                    foreach (ReceiveLocation rcl in rp.ReceiveLocations)
                    {
                        if (rcl.Enable != true)
                        {
                            rcl.Enable = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                application.BtsCatalogExplorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static void StopSendPorts(Application application)
        {

            try
            {
                foreach (SendPort sp in application.SendPorts)
                {
                    if (sp.Status != PortStatus.Stopped)
                    {
                        sp.Status = PortStatus.Stopped;
                    }
                }
            }
            catch (Exception ex)
            {
                application.BtsCatalogExplorer.DiscardChanges();
                EventLog.WriteEntry(BizMockEventSource, ex.Message, EventLogEntryType.Error);
                throw;
            }
        }

        public static void CreatePorts(Application application, List<IDeployPort> ports)
        {
            foreach (IDeployPort p in ports)
            {
                p.Deploy(application);
            }
        }



        /// <summary>
        /// Starts the host instances.
        /// </summary>
        public static void StartHostInstances()
        {
            ManagementScope scope = new ManagementScope(@"root\MicrosoftBizTalkServer");
            ManagementObjectSearcher searcher = null;
            ManagementObjectCollection hostCollection = null;
            var options = new EnumerationOptions { ReturnImmediately = false };

            var explorer = new BtsCatalogExplorer { ConnectionString = BizTalkConnectionString };
            foreach (Host host in explorer.Hosts)
            {
                if (host.Type != HostType.InProcess) continue;
                try
                {
                    var query = new SelectQuery("MSBTS_HostInstance",
                                                string.Format("HostName=\"{0}\"", host.Name));
                    searcher = new ManagementObjectSearcher(scope, query, options);
                    hostCollection = searcher.Get();
                    {
                        foreach (ManagementObject hostInstance in hostCollection)
                        {
                            var num = (uint)hostInstance["ServiceState"];
                            if (num != 4)
                            {
                                Debug.WriteLine("Starting " + host.Name + "...");
                                // it is running, restart it.
                                var objparams = new object[0];
                                hostInstance.InvokeMethod("Start", objparams);
                                Debug.WriteLine("Done.");
                            }
                            else
                            {
                                Debug.WriteLine("Host " + host.Name + " is already running");
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    EventLog.WriteEntry("BizMock", "Error stopping BizTalk hosts: " + ex.Message, EventLogEntryType.Error);
                    throw;
                }
                finally
                {
                    if (searcher != null)
                    {
                        searcher.Dispose();
                        searcher = null;
                    }
                    if (hostCollection != null)
                    {
                        hostCollection.Dispose();
                        hostCollection = null;
                    }
                }
            }
        }

        /// <summary>
        /// Stops the host instances.
        /// </summary>
        public static void StopHostInstances()
        {
            ManagementScope scope = new ManagementScope(@"root\MicrosoftBizTalkServer");

            ManagementObjectSearcher searcher = null;
            ManagementObjectCollection hostCollection = null;
            var options = new EnumerationOptions { ReturnImmediately = false };

            var explorer = new BtsCatalogExplorer { ConnectionString = BizTalkConnectionString };
            foreach (Host host in explorer.Hosts)
            {
                if (host.Type != HostType.InProcess) continue;
                try
                {
                    var query = new SelectQuery("MSBTS_HostInstance",
                                                string.Format("HostName=\"{0}\"", host.Name));
                    searcher = new ManagementObjectSearcher(scope, query, options);
                    hostCollection = searcher.Get();
                    {
                        foreach (ManagementObject hostInstance in hostCollection)
                        {
                            var num = (uint)hostInstance["ServiceState"];
                            if (num == 4)
                            {
                                Debug.WriteLine("Stopping " + host.Name + "...");
                                // it is running, restart it.
                                var objparams = new object[0];
                                hostInstance.InvokeMethod("Stop", objparams);
                                Debug.WriteLine("Done.");
                            }
                            else
                            {
                                Debug.WriteLine("Host " + host.Name + " is already stopped");
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    EventLog.WriteEntry("BizMock", "Error stopping BizTalk hosts: " + ex.Message, EventLogEntryType.Error);
                    throw;
                }
                finally
                {
                    if (searcher != null)
                    {
                        searcher.Dispose();
                        searcher = null;
                    }
                    if (hostCollection != null)
                    {
                        hostCollection.Dispose();
                        hostCollection = null;
                    }
                }
            }
        }

    }

    public sealed class SendPortInfo
    {
        public string Name { get; set; }

        public string TransportTypeData { get; set; }
    }

    public sealed class ReceiveLocationInfo
    {
        public string Name { get; set; }

        public string TransportTypeData { get; set; }
    }
}
